from PyQt6 import QtGui,QtCore
from PyQt6.QtWidgets import QWidget,QMessageBox,QApplication,QFileDialog
from main_ui import Ui_Form
from img_server import DailyDujingDaogaoImg
from chapter_indices import old_testament, new_testament
from datetime import date, timedelta
import sys
from chapterlib import chapter_generator
from pathlib import Path
from img_server import DailyDujingDaogaoImg
from threading import Thread
import winreg
import os
from subwin_template import subwin_template

init_text = '''周一
1为自己的心祷告
2为年轻人的灵魂得救祷告

周二
1为我们有能听的耳、受教的心祷告
2为牧者同工团队祷告

周三
1为我们的属灵生命祷告
2为约书亚团契祷告

周四
1为我们的信心祷告
2为荣美之家祝福祷告

周五
1为广州祝福祷告
2为约书亚团契周六的学习祷告

周六
1为国家祝福祷告
2为主日信息、敬拜及各项服事祷告

周日
1为年轻一代与神对齐、进入命定祷告
2为我们的父母祝福祷告'''


class main_window(QWidget, Ui_Form):
    def __init__(self):
        super().__init__()
        self.text_raw = init_text
        self.setupUi(self)
        self.img_obj = DailyDujingDaogaoImg()
        
        self.init_ui()

    def init_ui(self):
        
        # 有时间可以考虑重构
        # self.sender().property('text')或self.sender().property('objectName')
        # text属性是按钮的名称, objectName属性是按钮的对象名称
        # 可以确定发送方
        self.cbox_yue1.currentIndexChanged.connect(self.handle_cbox_juan1)
        self.cbox_yue2.currentIndexChanged.connect(self.handle_cbox_juan2)
        self.handle_cbox_juan1(0)
        self.handle_cbox_juan2(1)
        self.current_yue1 = self.cbox_yue1.currentIndex()
        self.current_yue2 = self.cbox_yue2.currentIndex()

        self.cbox_juan1.currentTextChanged.connect(self.handle_cbox_zhang1)
        self.cbox_juan2.currentTextChanged.connect(self.handle_cbox_zhang2)
        self.handle_cbox_zhang1('创世记')
        self.handle_cbox_zhang2('马太福音')
        
        # 更换内容模板
        self.btn_change_template.clicked.connect(self.handle_change_template)

        # 更换背景图案
        self.btn_change_bg.clicked.connect(self.handle_change_bg)
        # 生成一周图片
        self.btn_generate.clicked.connect(self.handle_generate)

        # 预览
        t = Thread(target=self.handle_preview, args=('__temp_default__',))
        t.start()
        # join会阻塞主线程
        # t.join()
        
        # 以下直接调用os.startfile是最方便的.(需要signal发送参数)
        # 但因为要判断文件中途否是被人删除, 放弃之
        # 当然也可以在自定义组件里判断, 但这不符合分工逻辑
        self.label_img.clicked.connect(self.handle_imgshowing)

    def handle_cbox_juan1(self, new_index):

        self.current_yue1 = self.cbox_yue1.currentIndex()
        if new_index == 0:
            self.cbox_juan1.clear()
            self.cbox_juan1.addItems(old_testament.keys())
        elif new_index == 1:
            self.cbox_juan1.clear()
            self.cbox_juan1.addItems(new_testament.keys())

    def handle_cbox_juan2(self, new_index):
        self.current_yue2 = self.cbox_yue2.currentIndex()
        if new_index == 0:
            self.cbox_juan2.clear()
            self.cbox_juan2.addItems(old_testament.keys())
        elif new_index == 1:
            self.cbox_juan2.clear()
            self.cbox_juan2.addItems(new_testament.keys())

    def handle_cbox_zhang1(self, new_key):
        # 必须加,否则报错
        # 级联选择时,会发送一次None
        if not new_key:
            return

        if self.current_yue1 == 0:
            count = old_testament.get(new_key)[1]
            zhang_list = [f'第{i:03}章' for i in range(1, count+1)]
            self.cbox_zhang1.clear()
            self.cbox_zhang1.addItems(zhang_list)
        elif self.current_yue1 == 1:
            count = new_testament.get(new_key)[1]
            zhang_list = [f'第{i:03}章' for i in range(1, count+1)]
            self.cbox_zhang1.clear()
            self.cbox_zhang1.addItems(zhang_list)

    def handle_cbox_zhang2(self, new_key):
        if not new_key:
            return

        if self.current_yue2 == 0:
            count = old_testament.get(new_key)[1]
            zhang_list = [f'第{i:03}章' for i in range(1, count+1)]
            self.cbox_zhang2.clear()
            self.cbox_zhang2.addItems(zhang_list)
        elif self.current_yue2 == 1:
            count = new_testament.get(new_key)[1]
            zhang_list = [f'第{i:03}章' for i in range(1, count+1)]
            self.cbox_zhang2.clear()
            self.cbox_zhang2.addItems(zhang_list)

    def parse_text(self):

        text_raw = self.plainTextEdit.toPlainText()
        options = ('周一', '周二', '周三', '周四', '周五', '周六', '周日')
        d = dict()
        key = 0
        values = []
        for line in text_raw.splitlines():
            line = line.strip()
            if line:
                if line in options:
                    #读取到新key就储存上次的k:v
                    #if key的作用是排除首次读取到的key,那时上次的k:v为空值
                    #也可以用if values,但因为程序逻辑变更,须存储所有用户输入的key,即使value为空
                    if key:
                        d[key] = values.copy()
                        values.clear()
                    key = week_info_to_int(line)
                else:
                    values.append(line)
        #除了排除首次空k:v,还要追加最后一次k:v
        if key:
            d[key] = values.copy()
            values.clear()
        return d

    def get_dates(self):
        today = date.today()

        init_day = None
        if self.btn_lastweek.isChecked():
            days = today.isoweekday()-1+7
            td = timedelta(days=days)
            init_day = today - td

        elif self.btn_thisweek.isChecked():
            days = today.isoweekday()-1
            td = timedelta(days=days)
            init_day = today - td
        elif self.btn_nextweek.isChecked():
            days = 7-today.isoweekday()+1
            td = timedelta(days=days)
            init_day = today + td
        ontday_to_add = timedelta(days=1)
        day_list = [init_day]
        for i in range(6):
            init_day += ontday_to_add
            day_list.append(init_day)

        return day_list

    def get_args(self):

        jing11 = self.cbox_juan1.currentText()
        jing21 = self.cbox_juan2.currentText()
        jing12 = self.cbox_zhang1.currentIndex()+1
        jing22 = self.cbox_zhang2.currentIndex()+1
        jing13 = self.cbox_vol1.currentIndex()+1
        jing23 = self.cbox_vol2.currentIndex()+1

        dujing_1_generator = chapter_generator(
            start=(jing11, jing12), capacity=jing13)
        dujing_2_generator = chapter_generator(
            start=(jing21, jing22), capacity=jing23)

        text_dict = self.parse_text()
        days = self.get_dates()
        return dujing_1_generator, dujing_2_generator, text_dict, days

    def handle_generate(self):
        text_raw = self.plainTextEdit.toPlainText().strip()
        text_len=len(text_raw)
        if not 3 < text_len < 500:
            self.msgbox('字数异常',f'确保能生成图片的字数为4~500个,\n你输入的字数为{text_len}个\n\n请选择你的操作:')
            return

        text_dict=self.parse_text()
        text_count=len(text_dict)
        
        # 不需要list(itertools.chain.from_iterable(text_dict.values()))
        # 内置的any函数即可
        if text_count and any(text_dict.values()):
            self.generation_count=text_count
        else:
            self.msgbox('有效内容为空','你输入的有效内容为空\n\n请选择你的操作:')
            return
        
        self.text_raw = text_raw

        p_dir_path = Path(get_desktop_path(),'荣美之家日常读经祷告信息')
        if not p_dir_path.exists() or p_dir_path.is_file():
            p_dir_path.mkdir()
        
        p_dir = QFileDialog.getExistingDirectory(
            self, '选择保存图片的目录', str(p_dir_path))

        if not p_dir:
            return

        self.btn_generate.setDisabled(True)
        self.btn_change_template.setDisabled(True)
        self.btn_change_bg.setDisabled(True)
        t = Thread(target=self.generate_task_for_threads, args=(p_dir,))
        t.start()

    def generate_task_for_threads(self, p_dir):
        dujing_1_generator, dujing_2_generator, text_dict, days = self.get_args()
        
        # 用新对象, 防止与预览图的对象混淆
        img_obj = DailyDujingDaogaoImg()
        img_obj.bg_img=self.img_obj.bg_img
        img_obj.template=self.img_obj.template
        #args = list(zip(dujing_1, dujing_2, daogao_list, days))
        
        for key in sorted(text_dict.keys()):
            dujing_1 = next(dujing_1_generator)
            dujing_2 = next(dujing_2_generator)
            if text_info:=text_dict.get(key):
                _day=days[key-1]
                #img_obj = DailyDujingDaogaoImg(dujing_1[i],dujing_2[i],text_info,_day)
                img_obj.dujing_1=dujing_1
                img_obj.dujing_2=dujing_2
                img_obj.daogao_info=text_info
                img_obj.share_date=_day
                
                f_name = Path(p_dir, f'{_day.month:02}月{_day.day:02}日【{img_obj.get_week_info()}】读经祷告.jpg')
                img_obj.generate_img(f_name)

        self.btn_generate.setEnabled(True)
        self.btn_change_template.setEnabled(True)
        self.btn_change_bg.setEnabled(True)
        
        os.startfile(p_dir)

    def handle_preview(self, file_name):
        self.img_obj.generate_img(file_name)
        pixmap = QtGui.QPixmap(file_name, 'jpg')
        #pixmap = pixmap.scaled(360,576,transformMode=QtCore.Qt.TransformationMode.SmoothTransformation)
        # self.label_img.setScaledContents(True)
        self.label_img.setPixmap(pixmap)
        Path(file_name).unlink()

    def handle_change_bg(self):
        img_name, img_type = QFileDialog.getOpenFileName(
            self, '请选择竖屏图片', 'bg_img', 'Images (*.jpg *.jpeg *.png)')

        if img_name:
            self.img_obj.bg_img = img_name
            
            t = Thread(target=self.handle_preview, args=('__temp__',))
            t.start()

    def handle_change_template(self):
        self.sub_exe = subwin_template(self)
        self.sub_exe.setWindowModality(QtCore.Qt.WindowModality.ApplicationModal)
        self.sub_exe.show()

    def handle_imgshowing(self):
        if not Path('__justforshow__.jpg').exists():
            # 不能用另外的线程执行
            # 因为要等它生成完毕才能打开
            # 严谨来说, 生成预览图也不能用多线程
            self.handle_preview('__temp__')
            
        os.startfile('__justforshow__.jpg')
    
    def msgbox(self,title:str,text:str):
            # 有两种方法自定义按钮, addButton和setStandardButtons
            # 前者如下, 后者需要messageBox.button(QMessageBox.Yes)取出按钮, 然后调用其setText('中文名')
            # 最后一律messageBox.clickedButton() == 自定义按钮进行判断
            msgbox=QMessageBox(self)
            msgbox.setIcon(QMessageBox.Icon.Warning)
            msgbox.setWindowTitle(title)
            msgbox.setText(text)
            btn_yes=msgbox.addButton('恢复到上次',QMessageBox.ButtonRole.YesRole)
            btn_reset=msgbox.addButton('恢复到默认',QMessageBox.ButtonRole.ResetRole)
            btn_no=msgbox.addButton('继续编辑',QMessageBox.ButtonRole.NoRole)
            clicked_button=msgbox.exec()
            
            if clicked_button == 0:
                self.plainTextEdit.setPlainText(self.text_raw)
            elif clicked_button == 1:
                self.plainTextEdit.setPlainText(init_text)

def week_info_to_int(week):
    week_dict = {'周一': 1, '周二': 2, '周三': 3,
                 '周四': 4, '周五': 5, '周六': 6, '周日': 7}
    return week_dict.get(week)

def get_desktop_path():
     key=winreg.OpenKey(winreg.HKEY_CURRENT_USER,'Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders')
     return winreg.QueryValueEx(key,"My Pictures")[0]

if __name__ == "__main__":
    app = QApplication([])

    app.setWindowIcon(QtGui.QIcon('icon.ico'))
    main_window = main_window()
    main_window.show()
    sys.exit(app.exec())
